///PHILOTES Source Code.  (C)2012 PhiloLabs

#include "OgreStableHeaders.h"
#include "OgreSimpleRenderable.h"
#include "core/exception.h"
#include "OgreSceneNode.h"

#include "OgreMaterialManager.h"

namespace Ogre {

    uint SimpleRenderable::msGenNameCount = 0;

    SimpleRenderable::SimpleRenderable()
 	: MovableObject()
 	, mWorldTransform(Matrix4::IDENTITY)
 	, mMatName("BaseWhite")
 	, mMaterial(MaterialManager::getSingleton().getByName("BaseWhite"))
 	, mParentSceneManager(NULL)
 	, mCamera(NULL)

    {
        // Generate name
		StringUtil::StrStreamType name;
		name << "SimpleRenderable" << msGenNameCount++;
		mName = name.str();
    }

 	SimpleRenderable::SimpleRenderable(const String& name)
 	: MovableObject(name)
 	, mWorldTransform(Matrix4::IDENTITY)
 	, mMatName("BaseWhite")
 	, mMaterial(MaterialManager::getSingleton().getByName("BaseWhite"))
 	, mParentSceneManager(NULL)
 	, mCamera(NULL)
 	{
 	}

    void SimpleRenderable::setMaterial( const String& matName )
    {
        mMatName = matName;
        mMaterial = MaterialManager::getSingleton().getByName(mMatName);
		if (mMaterial.isNull())
			PHILO_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + mMatName,
				"SimpleRenderable::setMaterial" );
    
        // Won't load twice anyway
        mMaterial->load();
    }

    const MaterialPtr& SimpleRenderable::getMaterial(void) const
    {
        return mMaterial;
    }

    void SimpleRenderable::getRenderOperation(RenderOperation& op)
    {
        op = mRenderOp;
    }

    void SimpleRenderable::setRenderOperation( const RenderOperation& rend )
    {
        mRenderOp = rend;
    }

    void SimpleRenderable::setWorldTransform( const Matrix4& xform )
    {
        mWorldTransform = xform;
    }

    void SimpleRenderable::getWorldTransforms( Matrix4* xform ) const
    {
        *xform = mWorldTransform * mParentNode->_getFullTransform();
    }

    void SimpleRenderable::_notifyCurrentCamera(Camera* cam)
    {
		MovableObject::_notifyCurrentCamera(cam);

        mCamera = cam;
    }

    void SimpleRenderable::setBoundingBox( const AxisAlignedBox& box )
    {
        mBox = box;
    }

    const AxisAlignedBox& SimpleRenderable::getBoundingBox(void) const
    {
        return mBox;
    }

    void SimpleRenderable::_updateRenderQueue(RenderQueue* queue)
    {
        queue->addRenderable( this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY); 
    }

	void SimpleRenderable::visitRenderables(Renderable::Visitor* visitor, 
		bool debugRenderables)
	{
		visitor->visit(this, 0, false);
	}

    SimpleRenderable::~SimpleRenderable()
    {
    }
    //-----------------------------------------------------------------------
    const String& SimpleRenderable::getMovableType(void) const
    {
        static String movType = "SimpleRenderable";
        return movType;
    }
    //-----------------------------------------------------------------------
    const LightList& SimpleRenderable::getLights(void) const
    {
        // Use movable query lights
        return queryLights();
    }

}
